var utils = (function () {

    var __class = function () { this.__self = this; };
    __class.prototype.getSelf = function (str) {
        return this.__self;
    }

    /*
     *  阻止事件冒泡
     *  @param  event   事件对象
     *  @retrun boolean
    */
    __class.prototype.noEventBubbling = function (event) {
        if (event && event.stopPropagation) {
            return event.stopPropagation();
        } else {
            return window.event.cancelBubble = true;
        }
    }

    /*
     *  取消默认事件
     *  @param  event   事件对象
     *  @retrun 无
    */
    __class.prototype.noDefaultEvent = function (event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            window.event.returnValue == false;
        }
    }

    /*
     *  对象克隆
     *  @param  obj   任意对象
     *  @retrun Object  克隆的新对象
    */
    __class.prototype.clone = function (obj) {
        var temp = null;
        if (obj instanceof Array) {
            temp = obj.concat();
        } else if (obj instanceof Function) {
            //函数是共享的是无所谓的，js也没有什么办法可以在定义后再修改函数内容
            temp = obj;
        } else {
            temp = new Object();
            for (var item in obj) {
                var val = obj[item];
                //这里也没有判断是否为函数，因为对于函数，我们将它和一般值一样处理
                temp[item] = typeof val == 'object' ? this.clone_new(val) : val;
            }
        }
        return temp;
    }

    /*
     *  获取13位当前时间戳
     *  @param  无
     *  @retrun number  13位当前时间戳
    */
    __class.prototype.timeStamp = function () {
        var time1;
        var date = new Date();
        // 有三种方式获取
        if (date.getTime) {
            time1 = date.getTime();
        } else if (date.valueOf) {
            time1 = date.valueOf();
        } else if (Date.parse) {
            time1 = Date.parse(date)
        }
        return time1;
    }

    /*
     *  将时间戳转换为时间字符串
     *  @param  time number 13位时间戳
     *  @param  flag boolean 可选参数，如果为true则返回json形式：
     *  @retrun string 2018-12-03 12:38:45  时间字符串
    */
    __class.prototype.datastring = function (time, flag) {
        var date = new Date(time);
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        var day = date.getDate();
        var hours = date.getHours();
        var mixins = date.getMinutes();
        var second = date.getSeconds();
        month = month < 10 ? "0" + month : month;
        day = day < 10 ? "0" + day : day;
        mixins = mixins < 10 ? "0" + mixins : mixins;
        second = second < 10 ? "0" + second : second;
        if (flag) {
            return { y: year, m: month, d: day, h: hours, M: mixins, s: second };
        } else {
            return year + "-" + month + "-" + day + " " + hours + ":" + mixins + ":" + second;
        }
    };

    /*
     *  存储本地存储
     *  @param  key any 任何可作为key的值
     *  @param  key val 任何可作为value的值
     *  @retrun 无
    */
    __class.prototype.setStoreage = function (key, val) {
        window.localStorage.setItem(key, JSON.stringify(val));
    }
    /*
     *  获取本地存储
     *  @param  key any 任何可作为key的值
     *  @param  flag any 可选参数，将返回值转换成JSON
     *  @retrun String或Object  对应key的value值
    */
    __class.prototype.getStoreage = function (key, flag) {
        return flag ? JSON.parse(window.localStorage.getItem(key)) : window.localStorage.getItem(key);
    }
    /*
     *  清空本地存储
     *  @param  key any 任何可作为key的值
     *  @retrun 无
    */
    __class.prototype.delStoreage = function (key) {
        window.localStorage.removeItem(key);
    }


    /* 
     *  生成指定位数的随机数
     *  @param  len number 生成位数
     *  @param  type num/str/all 生成类型，num为仅数字，str为仅字母，all为字母+数字（默认）
     *  @retrun  string 随机数字符串
    */
    __class.prototype.randString = function (len, type) {
        var text = "";
        var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        var possible;
        if (type == "num") {
            possible = "0123456789";
        } else if (type == "str") {
            possible = str;
        } else {
            possible = str + "0123456789";
        }
        for (var i = 0; i < len; i++) {
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        }
        return text;
    }

    /* 
     *  密码验证，规则：密码长度最少6位，必须包含 数字、字母、特殊字符，返回的值 小于3 则 复杂度不够
     *  @param  str string 要验证的字符串
     *  @retrun  boolean 是否合格
    */
    __class.prototype.checkPass = function (str) {
        if (str.length < 6) { return false; }
        var ls = 0;
        if (str.match(/([a-z])+/)) { ls++; }
        if (str.match(/([0-9])+/)) { ls++; }
        if (str.match(/([A-Z])+/)) { ls++; }
        if (str.match(/[^a-zA-Z0-9]+/)) { ls++; }
        return ls < 3;
    }

    /* 
     *  非空验证
     *  @param  str string 要验证的字符串
     *  @retrun  boolean 为空返回true
    */
    __class.prototype.isEmpty = function (str) {
        if (str == undefined || str == null) { return true; }
        return str == "" || str.replace(/\s+/g, "") == "" || str.length < 1;
    }

    /* 
     *  给document添加getElementClassName方法
     *  @param  className string 子节点类名
     *  @param  parentElement string 父节点对象
     *  @retrun  childDom[Array] 子节点对象组成的数组
    */
    __class.prototype.getElementClassName = function (className, parentElement) {
        parentElement = parentElement || document;
        if (parentElement.getElementsByClassName) {
            return parentElement.getElementsByClassName(className);
        } else {
            var boxClass = parentElement.getElementsByTagName('*');
            var arrClass = [];
            for (var i = 0; i < boxClass.length; i++) {
                // var name = boxClass[i].className;
                var nameBox = boxClass[i].className.split(' ');
                for (var j = 0; j < nameBox.length; j++) {
                    if (nameBox[j] == className) {
                        arrClass.push(boxClass[i]);
                    }
                };
            };
        }
        return (arrClass);
    }

    /* 
     *  计算2个时间差（常用定时器来实现倒计时）
     *  @param  sDate string 格式为：2015-9-30 8:15:6
     *  @param  flag boolean 可选参数，如果为true，则返回一个json格式： {d:天,h:小时,m:分钟,s:秒数}
     *  @retrun  默认返回固定字符串，存在第二个参数返回json形式
    */
    __class.prototype.CountDown = function (sDate, flag) {
        //endtime 为结束时间
        var endtime_ms = Date.parse(new Date(sDate.replace(/-/g, "/")));

        var date1 = new Date();  //开始时间
        var date2 = new Date(endtime_ms);    //结束时间
        var date3 = date2.getTime() - date1.getTime();  //时间差的毫秒数

        //计算出相差天数
        var days = Math.floor(date3 / (24 * 3600 * 1000));

        //计算出小时数
        var leave1 = date3 % (24 * 3600 * 1000);    //计算天数后剩余的毫秒数
        var hours = Math.floor(leave1 / (3600 * 1000));

        //计算相差分钟数
        var leave2 = leave1 % (3600 * 1000);        //计算小时数后剩余的毫秒数
        var minutes = Math.floor(leave2 / (60 * 1000));

        //计算相差秒数
        var leave3 = leave2 % (60 * 1000);     //计算分钟数后剩余的毫秒数
        var seconds = Math.round(leave3 / 1000);

        if (flag) {
            return { d: days, h: hours, m: minutes, s: seconds };
        } else {
            return (" 相差 " + days + "天 " + hours + "小时 " + minutes + " 分钟" + seconds + " 秒");
        };

    };

    /* 
     *  随机生成指定范围的数字
     *  @param  Min number 最小值
     *  @param  Max number 最大值
     *  @retrun  number 数字
    */
    __class.prototype.RandomNumBoth = function (Min, Max) {
        var Range = Max - Min;
        var Rand = Math.random();
        var num = Min + Math.round(Rand * Range); //四舍五入
        return num;
    };

    /* 
     *  等比例缩放图片大小
     *  @param  maxWidth number 最大宽度值
     *  @param  maxHeight number 最大高度值
     *  @param  imgelement element 图片节点/图片节点数组
     *  @retrun  无
    */
    __class.prototype.AutoResizeImage = function (maxWidth, maxHeight, imgelement) {

        function AutoImgSize(ele) {
            var image = new Image();
            image.src = ele.src;
            if (image.width > 0 && image.height > 0) {
                if (image.width / image.height >= maxWidth / maxHeight) {
                    if (image.width > maxWidth) {
                        ele.width = maxWidth;
                        ele.height = (image.height * maxWidth) / image.width;
                    } else {
                        ele.width = image.width;
                        ele.height = image.height;
                    };
                } else {
                    if (image.height > maxHeight) {
                        ele.height = maxHeight;
                        ele.width = (image.width * maxHeight) / image.height;
                    } else {
                        ele.width = image.width;
                        ele.height = image.height;
                    };
                };
            };
        };

        if (imgelement.length != undefined) {
            for (var t = 0; t < imgelement.length; t++) {
                AutoImgSize(imgelement[t]);
            };
        } else {
            AutoImgSize(imgelement);
        };
    };


    /* 
     *  让Array.prototype以下的方法可以操作任何对象
     *  @retrun  无
    */
    __class.prototype.ArrayForObject = function () {
        Function.prototype.uncurrying = function () {
            var self = this;
            return function () {
                var obj = Array.prototype.shift.call(arguments);
                return self.apply(obj, arguments);
            };
        };

        //遍历Array.prototype下的3个方法，使能够操作任何对象
        for (var i = 0, fn, ary = ['push', 'shift', 'forEach']; fn = ary[i++];) {
            Array[fn] = Array.prototype[fn].uncurrying();
        };
    }

    /* 
     *  限制触发频率，函数节流
     *  @retrun  无
    */
    __class.prototype.throttle = function (fn, interval) {
        var __self = fn, // 保存需要被延迟执行的函数引用
        timer, // 定时器
        firstTime = true; // 是否是第一次调用
        return function () {
            var args = arguments,__me = this;
            if (firstTime) { // 如果是第一次调用，不需延迟执行
                __self.apply(__me, args);
                return firstTime = false;
            }
            if (timer) { // 如果定时器还在，说明前一次延迟执行还没有完成
                return false;
            }
            timer = setTimeout(function () { // 延迟一段时间执行
                clearTimeout(timer);
                timer = null;
                __self.apply(__me, args);
            }, interval || 500);
        };
    }

    /* 
     *  分批处理函数
     *  @param  len number 总操作次数
     *  @param  fn number 每次操作函数
     *  @param  count number 每次执行操做的个数
     *  @retrun  无
    */
   __class.prototype.timeChunk = function (len, fn, count) {

        var ary = [];
        for (var i = 1; i <= len; i++) {
            ary.push(i);
        };

        var obj,
            t;
        var len = ary.length;
        var start = function () {
            for (var i = 0; i < Math.min(count || 1, ary.length); i++) {
                var obj = ary.shift();
                fn(obj);
            }
        };
        return function () {
            t = setInterval(function () {
                if (ary.length === 0) { // 如果全部节点都已经被创建好
                    return clearInterval(t);
                }
                start();
            }, 200); // 分批执行的时间间隔，也可以用参数的形式传入
        };
    };

    return new __class();
})();